﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Automation;

namespace SoundSwitch
{
    class Program
    {
        static void Main(string[] args)
        {
            var p = Process.Start("rundll32.exe", "Shell32.dll,Control_RunDLL mmsys.cpl,,playback");
            Console.WriteLine("mmsys launched. {0}", p.Id);

            var e = GetMainWindow(p, "Sound", "#32770");
            Console.WriteLine("Main window found. {0}", e.Current.NativeWindowHandle);

            var list = e.FindFirst(TreeScope.Descendants,
                new PropertyCondition(AutomationElement.AutomationIdProperty, "1000"));
            Console.WriteLine("List found. {0}", list.Current.NativeWindowHandle);
          
            var defaultBtn = e.FindFirst(TreeScope.Descendants,
                new PropertyCondition(AutomationElement.AutomationIdProperty, "1002"));
            Console.WriteLine("Default button found. {0}", defaultBtn.Current.NativeWindowHandle);

            var devices = GetDevices(list);
            Console.WriteLine("Device found. {0}", devices.Length);

            foreach (var device in devices)
            {               
                SelectItem(device);
                Console.WriteLine("Select device {0}.", device.Current.Name);

                if (defaultBtn.Current.IsEnabled)
                {
                    InvokeButton(defaultBtn);
                    Console.WriteLine("Set as default.");
                    break;
                }
                else
                {
                    Console.WriteLine("It is default.");
                }
            }

            CloseWindow(e);
        }

        private static void InvokeButton(AutomationElement e)
        {
            var button = e.GetCurrentPattern(InvokePatternIdentifiers.Pattern)
                    as InvokePattern;
            button.Invoke();
        }

        private static void SelectItem(AutomationElement e)
        {
            var item = e.GetCurrentPattern(SelectionItemPatternIdentifiers.Pattern)
                    as SelectionItemPattern;
            item.Select();
        }

        private static void CloseWindow(AutomationElement e)
        {
            var window = e.GetCurrentPattern(WindowPatternIdentifiers.Pattern)
                as WindowPattern;
            window.Close();
        }

        private static AutomationElement[] GetDevices(AutomationElement e)
        {
            var grid = e.GetCurrentPattern(GridPatternIdentifiers.Pattern)
                as GridPattern;
            return new AutomationElement[] { grid.GetItem(0, 0), grid.GetItem(1, 0) };
        }

        private static AutomationElement GetMainWindow(Process p, string caption, string className)
        {
            AutomationElement e = null;
            while ((e = AutomationElement.RootElement.FindFirst(TreeScope.Children, new AndCondition(
                    new PropertyCondition(AutomationElement.ProcessIdProperty, p.Id),
                    // temporary disable name property cos it cause localization issue
                    //new PropertyCondition(AutomationElement.NameProperty, caption),
                    new PropertyCondition(AutomationElement.ClassNameProperty, className)
                    ))) == null)
            {
                Thread.Sleep(200);
            }
            return e;
        }
    }
}
